package com.wss.lsl.test.driven.runnable;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * 多线程执行job的两个方法：所有doJob1()执行完之后，doJob2()才开始执行.
 * <p>
 * 使用关卡实现，doJob1()执行完之后，在关卡等待，直到最后一个线程执行完才打开关卡
 * </p>
 * 
 * @author Administrator
 * 
 */
public class Job {

	public void doJob1() {
		System.out.println("doJob1");
	}

	public void doJob2() {
		System.out.println("doJob2");
	}

	public void run(int threadCount) {
		CyclicBarrier entryBarrier = new CyclicBarrier(threadCount);
		CyclicBarrier exitBarrier = new CyclicBarrier(threadCount + 1);
		for (int i = 0; i < threadCount; i++) {
			new Thread(new RunJob(this, entryBarrier, exitBarrier)).start();
		}
		try {
			exitBarrier.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
	}

	static class RunJob implements Runnable {

		private Job job;
		// 进入的关卡
		private CyclicBarrier entryBarrier;
		// 退出的关卡
		private CyclicBarrier exitBarrier;

		public RunJob(Job job, CyclicBarrier entryBarrier,
				CyclicBarrier exitBarrier) {
			super();
			this.job = job;
			this.entryBarrier = entryBarrier;
			this.exitBarrier = exitBarrier;
		}

		@Override
		public void run() {
			try {
				job.doJob1();
				// 在关卡等待，直到所有的doJob1执行完
				entryBarrier.await();
				job.doJob2();
				// 配合主线程退出，避免主线程退出而导致程序关闭
				exitBarrier.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (BrokenBarrierException e) {
				e.printStackTrace();
			}
		}

	}
}
